package pl.allegro.tech.hermes.management.domain.subscription.health.problem;

import static pl.allegro.tech.hermes.api.SubscriptionHealthProblem.malfunctioning;

import java.util.Optional;
import pl.allegro.tech.hermes.api.SubscriptionHealthProblem;
import pl.allegro.tech.hermes.management.domain.subscription.health.SubscriptionHealthContext;
import pl.allegro.tech.hermes.management.domain.subscription.health.SubscriptionHealthProblemIndicator;

public class MalfunctioningIndicator implements SubscriptionHealthProblemIndicator {
  private final double max5xxErrorsRatio;
  private final double minSubscriptionRateForReliableMetrics;

  public MalfunctioningIndicator(
      double max5xxErrorsRatio, double minSubscriptionRateForReliableMetrics) {
    this.max5xxErrorsRatio = max5xxErrorsRatio;
    this.minSubscriptionRateForReliableMetrics = minSubscriptionRateForReliableMetrics;
  }

  @Override
  public Optional<SubscriptionHealthProblem> getProblem(SubscriptionHealthContext context) {
    if (areSubscriptionMetricsReliable(context) && isCode5xxErrorsRateHigh(context)) {
      return Optional.of(
          malfunctioning(
              context.getCode5xxErrorsRate(),
              context.getSubscription().getQualifiedName().toString()));
    }
    return Optional.empty();
  }

  private boolean areSubscriptionMetricsReliable(SubscriptionHealthContext context) {
    return context.getSubscriptionRateRespectingDeliveryType()
        > minSubscriptionRateForReliableMetrics;
  }

  private boolean isCode5xxErrorsRateHigh(SubscriptionHealthContext context) {
    double code5xxErrorsRate = context.getCode5xxErrorsRate();
    double rate = context.getSubscriptionRateRespectingDeliveryType();
    return code5xxErrorsRate > max5xxErrorsRatio * rate;
  }
}
